import os
import logging
import time

from fastapi.responses import JSONResponse
from fastapi import FastAPI, Request, UploadFile, File
from pydub import AudioSegment
from pydub.silence import detect_nonsilent
from starlette.responses import RedirectResponse, FileResponse

from . import business, input_dir, output_dir, utils

Title = '音频人声提取接口'
app = FastAPI(title=Title)
LOG = logging.getLogger(__name__)


@app.get("/", summary="无index页面，将重定向到'{}'页面".format(Title))
def index(request: Request):
    return RedirectResponse("{}docs".format(request.url))


@app.put("/audio/separate", summary="上传一个音频文件到input文件夹")
async def put_audio_separate(file: UploadFile = File(...)):
    try:
        task = business.Separate(file.filename)
    except Exception as e:
        return JSONResponse(status_code=400, content={"filename": file.filename, 'result': str(e)})
    else:
        content = await file.read()
        filepath = os.path.join(input_dir, file.filename)
        with open(filepath, 'wb') as f:
            f.write(content)
        task.start()
        return {"filename": file.filename}


@app.get("/audio/separate", summary="查询分离人声任务是否成功")
def get_audio_separate():
    if not business.Separate.Instance:
        return {"task": 'no task'}
    else:
        return getattr(business.Separate.Instance, 'status')


@app.get("/audio/detect_silent", summary="根据静默时间返回指定音频编号的时间片段")
def time_point(filename: str, number: int):
    try:
        start_time = time.perf_counter()
        if '.' in filename:
            filename = filename.split('.')[0]
        base_dir = os.path.join(output_dir, filename)
        fullname = utils.get_number_file_fullname(base_dir, number)
        filepath = os.path.join(base_dir, fullname, 'vocals.mp3')
        if not os.path.exists(filepath):
            return JSONResponse(status_code=400, content={"result": '{} not exist'.format(filepath)})
        sound = AudioSegment.from_mp3(filepath)
        chunks = detect_nonsilent(sound, min_silence_len=430, silence_thresh=-45)  # ,keep_silence=400)
        used_time = int(time.perf_counter() - start_time)
        result = {'task': filename, 'used_time': used_time, 'length': len(sound), 'result': chunks}
        LOG.info(result)
        return result
    except Exception as e:
        return JSONResponse(status_code=400, content={"result": str(e)})


@app.get("/dir/input", summary="返回input文件夹内文件tree结构")
def get_input_tree():
    return utils.get_path_tree(input_dir)


@app.get("/dir/output", summary="返回output文件夹内文件tree结构")
def get_output_tree():
    return utils.get_path_tree(output_dir)


@app.get("/download", summary="下载容器内任意文件")
async def download(filepath):
    if not os.path.exists(filepath):
        return JSONResponse(status_code=400, content={'result': '{} is not exist'.format(filepath)})
    return FileResponse(filepath, filename=os.path.basename(filepath))
